package com.tabjin.rfidsocket.authority.shiro;

import com.tabjin.rfidsocket.authority.shiro.model.Permission;
import com.tabjin.rfidsocket.authority.shiro.model.Role;
import com.tabjin.rfidsocket.authority.shiro.model.User;
import com.tabjin.rfidsocket.authority.shiro.model.vo.PermissionVO;
import com.tabjin.rfidsocket.authority.shiro.model.vo.RoleVO;
import com.tabjin.rfidsocket.authority.shiro.model.vo.UserVO;
import com.tabjin.rfidsocket.authority.shiro.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author tabjin
 * create at 2020/12/16 17:30
 * @program rfid_socket
 * @description
 */
public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**
     * 授权（验证权限时调用）
     * 授权是在用户认证登录之后，会将user对象放到session中
     * 所以在授权时需要在session中取出user对象
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        UserVO userVO = (UserVO) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
        List<String> permissionList = new ArrayList<>();// 权限
        List<String> roleNameList = new ArrayList<>();// 角色名列表
        Set<RoleVO> roleVOSet = userVO.getRoles();
        if (CollectionUtils.isNotEmpty(roleVOSet)) {// 角色不为空
            for (RoleVO roleVO : roleVOSet) {
                roleNameList.add(roleVO.getRoleName());// 加入角色名
                Set<PermissionVO> permissionVOSet = roleVO.getPermissions();
                if (CollectionUtils.isNotEmpty(roleVOSet)) {
                    for (PermissionVO permissionVO : permissionVOSet) {
                        permissionList.add(permissionVO.getPermissionName());// 根据权限名判断用户
                        System.out.println("permissionVO.getPermissionName():" + permissionVO.getPermissionName());
                    }
                }
            }
        }
        //
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionList);// 加入权限
        info.addRoles(roleNameList);// 加入角色授权
        return info;
    }

    /**
     * 认证登录（验证登录是时调用）
     *
     * @param authenticationToken 多态形式的令牌对象
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = usernamePasswordToken.getUsername();
        UserVO userVO = userService.findByUsername(username);
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userVO,
                userVO.getPassword(),
                this.getClass().getName());
        return simpleAuthenticationInfo;
    }
}
